#include "stdafx.h"
#include "YProactorTokenOnAccept.h"
#include "ITcpSessionCallback.h"
#include <WinSock2.h>
#include <MSWSock.h>
#include "ITcpSession.h"
#include <YSimpleSystem/IProactor.h>
#include <YSimpleSystem/YSimpleSystem.h>

namespace ysimple_network
{
	YProactorTokenOnAccept::YProactorTokenOnAccept(void)
		: m_pCallback(nullptr)
		, m_pNewSession(nullptr)
		, m_pProactor(nullptr)
	{
		
	}


	YProactorTokenOnAccept::~YProactorTokenOnAccept(void)
	{
	}

	void YProactorTokenOnAccept::beginInit( ITCPSession& newSession, IAcceptCallback& callback, ysimple_system::IProactor& proactor )
	{
		resetOverlapped();

		m_pCallback = &callback;
		m_pNewSession = &newSession;
		m_pNewSession->addRef();
		m_pProactor = &proactor;
		ZeroMemory(m_addressBuffer, sizeof(m_addressBuffer));
	}


	bool YProactorTokenOnAccept::onCompleted( bool completionStatus, LONG_PTR completionKey, DWORD dwBytesTransfered )
	{
		ITCPSession* pListenSession = (ITCPSession*)completionKey;
		
		SOCKET listenSocket = pListenSession->getSocket();
		setsockopt( m_pNewSession->getSocket(), 
			SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, 
			(char *)&listenSocket, 
			sizeof(SOCKET)
			);
		
		
		m_pProactor->associate((HANDLE)m_pNewSession->getSocket(), m_pNewSession);
		m_pCallback->onAccepted(*pListenSession,  *m_pNewSession);
		m_pNewSession->release();
		return true;
	}

	char* YProactorTokenOnAccept::getAddressBuffer()
	{
		return m_addressBuffer;
	}

	size_t YProactorTokenOnAccept::getAddressBufferSize()
	{
		return sizeof(SOCKADDR_STORAGE)+16;
	}

	void YProactorTokenOnAccept::endInit( bool success )
	{
		if (success == false)
		{
			m_pNewSession->release();
		}
	}

	
}
